home *** CD-ROM | disk | FTP | other *** search
/ C/C++ Users Group Library 1997 August / Walnut Creek CDROM.7z / LISTINGS / V_13_11 / WEISFELD / SEMA.CPP < prev    next >
Encoding:
C/C++ Source or Header  |  1995-09-10  |  5.2 KB  |  305 lines

  1. //**************************************************
  2. //  Listing 3
  3. //
  4. //  FILE NAME   : sema.cpp
  5. //  AUTHOR      : Matt Weisfeld
  6. //
  7. //  DESCRIPTION : using semaphores and critical
  8. //                     sections to synchronize processes.
  9. //
  10. //**************************************************
  11. // Example : For 3 processes
  12. //
  13. // Pn - process (P0 is the master)
  14. // T  - turn variable
  15. // Sn - status
  16. //
  17. // P0 P1 P2 T S1 S2
  18. //
  19.  
  20. #include <iostream.h>
  21. #include <stdlib.h>
  22. #include <string.h>
  23. #include "sema.h"
  24.  
  25. // DESCRIPTION : constructor
  26. semaphore::semaphore (long processes)
  27. {
  28.     strcpy (filename,FILENAME);
  29.  
  30.     // Initialize the number of processess and the
  31.     // appropriate arrays.
  32.     PROCESSES = processes;
  33.     for (int loop_i = 0; loop_i < PROCESSES; loop_i++) {
  34.         NODE[loop_i] = loop_i;
  35.         LOC[loop_i] = PROCESSES+loop_i;
  36.     };
  37. };
  38.  
  39. // DESCRIPTION : dummy destructor
  40. semaphore::~semaphore(void){};
  41.  
  42. // DESCRIPTION : synchronize using critical sections
  43. void semaphore::synchronize(char *param) {
  44.  
  45.     // If the parameter is an 'i', simply initialize
  46.     // the shared file then exit
  47.     if (!strcmp (param, "i")) {
  48.         initialize();
  49.         exit(0);
  50.     };
  51.  
  52.     node = atoi(param);     // identify the current node
  53.     intro();        // print out informational messages
  54.     i = node;          // use 'i' since algorithm does
  55.     turn_num=0;
  56.     flag_num=0;
  57.     critical_status=NORMAL;
  58.  
  59.     // Perform critical function until exit condition exists
  60.     while (critical_status == NORMAL) {
  61.         perform();
  62.     }
  63.     return;
  64. }
  65.  
  66. // DESCRIPTION : contains the CS algorithm
  67. void semaphore::perform(void)
  68. {
  69.  
  70.     //    A do-while (!expression) is the same as
  71.     //      do-until (expression)
  72.  
  73.     // See algorithm for description of the code.
  74.  
  75.     do {
  76.  
  77.         cs_write ( i, WANT_IN);
  78.  
  79.         turn_num = cs_read ( LOC[0]);
  80.  
  81.         j = turn_num;
  82.  
  83.         while (j != i) {
  84.  
  85.             flag_num = cs_read ( j);
  86.  
  87.             if (flag_num != IDLE) {
  88.  
  89.                 turn_num = cs_read ( LOC[0]);
  90.  
  91.                 j = turn_num;
  92.  
  93.             } else {
  94.             
  95.  
  96.                 j = (j+1) % PROCESSES;
  97.  
  98.  
  99.             }
  100.  
  101.         }
  102.  
  103.         cs_write ( i, IN_CS);
  104.     
  105.         
  106.         j = 0;
  107.  
  108.         flag_num = cs_read ( j);
  109.  
  110.         while ( (j<PROCESSES-1) && (j==i || flag_num!=IN_CS) ) {
  111.  
  112.             j++;
  113.  
  114.             flag_num = cs_read ( j);
  115.  
  116.         }
  117.  
  118.         turn_num = cs_read ( LOC[0]);
  119.  
  120.         flag_num = cs_read ( turn_num);
  121.  
  122.     }while (!((j>=PROCESSES-1) && ((turn_num == i) || flag_num == IDLE)));
  123.  
  124.     turn_num = i;
  125.  
  126.     cs_write ( LOC[0], turn_num);
  127.  
  128.  
  129.     // enter critical section
  130.  
  131.     critical_status = critical_section();
  132.  
  133.     // leave critical section
  134.  
  135.     turn_num = cs_read ( LOC[0]);
  136.  
  137.     j = (turn_num+1) % PROCESSES;
  138.  
  139.     flag_num = cs_read ( j);
  140.  
  141.     while (flag_num == IDLE) {
  142.  
  143.         j = (j+1) % PROCESSES;
  144.  
  145.         flag_num = cs_read ( j);
  146.  
  147.     }
  148.  
  149.     turn_num = j;
  150.  
  151.     cs_write ( LOC[0], turn_num);
  152.  
  153.     flag_num = IDLE;
  154.  
  155.     cs_write ( i, flag_num);
  156.  
  157.     return;
  158. };
  159.  
  160. // DESCRIPTION : identify the node
  161. void semaphore::intro(void)
  162. {
  163.  
  164.     printf ("PROCESSOR NODE %d\n", node);
  165.  
  166.     return;
  167.  
  168. };
  169.  
  170. // DESCRIPTION : initialize the shared data file
  171. void semaphore::initialize(void) {
  172.  
  173.     FILE *fp;
  174.     long loc = 0, zero=0;
  175.  
  176.     printf ("Initialize\n");
  177.  
  178.     if ((fp = fopen(filename, "w+")) == NULL){
  179.         printf ("initialize: can't open %s\n", filename);
  180.         exit(0);
  181.     };
  182.  
  183.     // Initialize all status variables and flags to zero
  184.     for (loc = 0; loc < (PROCESSES + 1 + (PROCESSES-1)); loc++) {
  185.  
  186.         if (fseek (fp, loc*2, ORIGIN) != 0) {
  187.             printf ("ERROR: fseek error in initialize\n");
  188.             exit(0);
  189.         };
  190.  
  191.         if (fprintf (fp, "%ld ", zero) < 0) {
  192.             printf ("ERROR: initialize error\n");
  193.             exit(0);
  194.         };
  195.  
  196.     };
  197.  
  198.     // Simply for clarity, mark the end of the flags with
  199.     // an 'X'
  200.     if (fseek (fp, loc*2, ORIGIN) != 0) {
  201.         printf ("ERROR: fseek error in initialize\n");
  202.         exit(0);
  203.     };
  204.  
  205.     if (fprintf (fp, "%c ", 'X') < 0) {
  206.         printf ("ERROR: initialize error\n");
  207.         exit(0);
  208.     };
  209.  
  210.     fclose (fp);
  211.  
  212. };
  213.  
  214. // DESCRIPTION : actual critical section
  215. long semaphore::critical_section(void)
  216. {
  217.     int loop_i;
  218.     long status;
  219.  
  220.     // If the node is the master (node 0) then see if all
  221.     // other nodes are ready. If they are, then clear all
  222.     // appropriate variables and the shared file. If all
  223.     // not ready, try again.
  224.  
  225.     if (node == 0) {
  226.  
  227.             status = READY;
  228.             for (loop_i=1; loop_i<PROCESSES; loop_i++) {
  229.                 NODE_NUM[loop_i] = cs_read(LOC[loop_i]);
  230.                 if (NODE_NUM[loop_i] != READY)
  231.                     status=CLEAR;
  232.             };
  233.  
  234.             if (status == READY) {
  235.                 for (loop_i=1; loop_i<PROCESSES; loop_i++) {
  236.  
  237.                     NODE_NUM[loop_i] = CLEAR;
  238.                     cs_write(LOC[loop_i], NODE_NUM[loop_i]);
  239.                 }
  240.                 return(STOP);
  241.  
  242.             } else {
  243.  
  244.                 return(NORMAL);
  245.  
  246.             }
  247.  
  248.     } else {         // if non-master node, mark node as ready
  249.  
  250.         NODE_NUM[node] = READY;
  251.         cs_write(LOC[node], NODE_NUM[node]);
  252.         return(STOP);
  253.     }
  254. };
  255.  
  256. // DESCRIPTION : write to the shared file
  257. void semaphore::cs_write(long loc, long value)
  258. {
  259.     FILE *fp;
  260.  
  261.     if ((fp = fopen(filename, "r+")) == NULL){
  262.         printf ("cs_write: can\'t open %s\n", filename);
  263.         exit(0);
  264.     };
  265.  
  266.     if (fseek (fp, loc*2, ORIGIN) != 0) {
  267.         printf ("ERROR: fseek error in cs_write\n");
  268.         exit(0);
  269.     };
  270.  
  271.     if (fprintf (fp, "%ld ", value) < 0) {
  272.         printf ("ERROR: cs_write error\n");
  273.         exit(0);
  274.     };
  275.  
  276.     fclose (fp);
  277.  
  278.     return;
  279. };
  280.  
  281. // DESCRIPTION : read from the shared file
  282. long semaphore::cs_read(long loc)
  283. {
  284.  
  285.     FILE *fp;
  286.     long value;
  287.  
  288.     if ((fp = fopen(filename, "r")) == NULL){
  289.  
  290.         printf ("cs_read: can't open %s\n", filename);
  291.         exit(0);
  292.  
  293.     };
  294.  
  295.     if (fseek (fp, loc*2, ORIGIN) != 0)
  296.         printf ("ERROR: fseek error in cs_read\n");
  297.     if (fscanf (fp ,"%ld", &value) == EOF)
  298.         printf ("ERROR: cs_read error\n");
  299.  
  300.     fclose (fp);
  301.  
  302.     return(value);
  303. };
  304.  
  305.